← BACK TO BlOG ← BACK TO PORTFOLIO
BLOG

A Look Into My Open GL Game Engine

2026-09-16
My Project

Core Features

UI + Text Rendering

UI And Text

Something I spent alot of time working on was creating usable UI in my program With my implementations, I integrated text rendering and nine-sliced UI rendering, both of which allow me to crate interesting user-interfaces

Shadow Mapping

Shadows

Shadow rendering was an interesting challenge, to achieve this, I had to render depth from a directional lights point of view and then apply a transformation in-shader projected into the main cameras point of view. By doing this I can calculate which areas are in shadow relative to the main camera and which are not.

Assuming we have the light space coords, we can calculate the screen coords to sample the shadow texture of

FragPosLightSpace = LightVP * vec4(FragPos, 1.0);

vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;

We can now sample the shadow texture in order to get whats in shadow and whats not

texture(ShadowMap, projCoords.xy)

I go through an extra step in order to sample smooth shadows but this is not nesseccary for shadow-sampling and simply improves the result

Smooth Shadows

Deffered Rendering

Deffered Rendering

I also integrated deffered rendering, this can allow me to add 100+ lights into the scene each affecting models individually, this also allows me more in-depth control over the rendering pipeline and allows for custom effects to be passed in between texture passes

These objects being rendered are also being rendered instanced so its a few draw calls instead of thousends, doing this improve performance of the application thoroughly

Custom Material + Shader File Loading

Custom Shaders

One thing I found annoying about the process was the implementation of new shaders, they would need a .vert component and a .frag component. To solve this, I solution i came up with was to combine them into a single .shader file which contained both a .vert and .frag component

Multi Pass Shaders

In order to be able to to this, I append a define into the shader which the program then can check what define is currently being written in order to compile either the .vert or .frag component, This helped keep my project clean and tidy and avoided unnecessary extra files.

List Of Shaders

Above is the list of shaders my program contains, without this compact method